home *** CD-ROM | disk | FTP | other *** search
- /*
- * MandelVroom 2.0
- *
- * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
- *
- * All rights reserved.
- *
- * Permission is hereby granted to distribute this program's source
- * executable, and documentation for non-comercial purposes, so long as the
- * copyright notices are not removed from the sources, executable or
- * documentation. This program may not be distributed for a profit without
- * the express written consent of the author Kevin L. Clague.
- *
- * This program is not in the public domain.
- *
- * Fred Fish is expressly granted permission to distribute this program's
- * source and executable as part of the "Fred Fish freely redistributable
- * Amiga software library."
- *
- * Permission is expressly granted for this program and it's source to be
- * distributed as part of the Amicus Amiga software disks, and the
- * First Amiga User Group's Hot Mix disks.
- *
- * contents: this file contains the functions used to implement MandelVroom's
- * pan command. It seems to have a bug when resizing pictures slightly
- * smaller.
- */
-
- #include "mandp.h"
-
- static int ScrollHotX, ScrollHotY;
-
- UBYTE ScrollOn = 1;
-
- #ifdef TEMPWINDOW
- #define SAFEBLIT
-
- static struct NewWindow NewTemp = {
- 0,12, /* start position */
- 80,80, /* width, height */
- (UBYTE) 0, (UBYTE) NORMALPEN,
- MOUSEBUTTONS, /* IDCMP flags */
- /* MandWind flags */
- WINDOWDRAG | NOCAREREFRESH | SMART_REFRESH,
- (struct Gadget *) NULL, /* first gadget */
- (struct Image *) NULL, /* user checkmark */
- (UBYTE *) NULL, /* Title */
- (struct Screen *) NULL, /* pointer to screen */
- (struct BitMap *) NULL, /* pointer to superbitmap */
- 20,20,-1,-1, /* sizing */
- CUSTOMSCREEN /* type of screen */
- };
-
- static struct Window *TempWind;
- #endif
-
- ScrollPictCmd(Msg)
- struct IntuiMessage *Msg;
- {
- struct Window *Window;
- static struct Picture *Pict;
-
- Window = Msg->IDCMPWindow;
- Pict = (struct Picture *) Window->UserData;
-
- switch( Msg->Class ) {
- case NEWSIZE:
- if (CurPict && (CurPict->Flags & SCROLL_HAPPENED)) {
- MoveClipImage(CurPict);
- }
- break;
-
- case MENUPICK:
- switch( SUBNUM(Msg->Code) ) {
- case SETSCROLL:
- State = SCROLLPICTSTATE;
- ThrowTask(CurPict);
- if ( ! (CurPict->Flags & SCROLL_HAPPENED)) {
-
- if ( AllocScrollTemp(CurPict) == UNSUCCESSFUL ) {
- return;
- }
- SaveInitialImage(CurPict);
- }
- CurPict->Flags |= SCROLL_HAPPENED;
- SetToPointer();
- break;
-
- case GENSCROLL:
- if (CurPict && CurPict->Flags & SCROLL_HAPPENED) {
- Generate(CurPict);
- }
- break;
-
- case CANCELSCROLL:
- ReColor(CurPict);
- break;
- }
- break;
-
- case MOUSEBUTTONS:
- switch( Msg->Code ) {
-
- case SELECTDOWN: /* start drag */
- if (Pict == NULL || Pict != CurPict) {
- return;
- }
- ScrollHotX = MouseX - CurPict->ImageLoc.Left;
- ScrollHotY = MouseY - CurPict->ImageLoc.Top;
- Scroll( CurPict);
- ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
- break;
-
- case SELECTUP: /* stop slide */
- ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
- break;
- }
- break;
-
- case MOUSEMOVE:
- Scroll( CurPict);
- break;
- }
- }
-
- SaveInitialImage(Pict)
- struct Picture *Pict;
- {
- #ifdef SAFEBLIT
- SafeClipBlit(Pict->Window, Pict->LeftMarg, Pict->TopMarg,
- TempWind, 0, 0,
- Pict->CountX, Pict->CountY,
- 0xc0, __LINE__);
- #else
- ClipBlit(Pict->Window->RPort, Pict->LeftMarg, Pict->TopMarg,
- &Pict->ScrollRp, 0, 0,
- Pict->CountX, Pict->CountY,
- 0xc0);
- #endif
- }
-
- Scroll( Pict )
- struct Picture *Pict;
- {
- CalcNewLoc(Pict,MouseX,MouseY); /* figure out location of new image */
- MoveClipImage(Pict);
- }
-
- CalcNewLoc(Pict, MouseX, MouseY)
- register struct Picture *Pict;
- int MouseX, MouseY;
- {
- /* set new ImageLoc */
-
- Pict->ImageLoc.Top = MouseY - ScrollHotY;
- Pict->ImageLoc.Left = MouseX - ScrollHotX;
- Pict->ImageLoc.Bot = Pict->ImageLoc.Top + Pict->CountY;
- Pict->ImageLoc.Right = Pict->ImageLoc.Left + Pict->CountX;
- }
-
- MoveClipImage(Pict)
- register struct Picture *Pict;
- {
- struct Window *Window;
- struct RastPort *wind_Rp, *tmp_Rp;
-
- register int POLeft, PORight, POTop, POBot;
-
- struct Rect SaveRect;
- struct Rect DispRect;
-
- Window = Pict->Window;
-
- SaveRect = Pict->ClipImage; /* struct assign */
-
- DispRect.Left = Pict->LeftMarg;
- DispRect.Top = Pict->TopMarg;
- DispRect.Right = Window->Width - Pict->RightMarg - 1;
- DispRect.Bot = Window->Height - Pict->BotMarg - 1;
-
- if (Pict->ImageLoc.Left > DispRect.Right ||
- Pict->ImageLoc.Top > DispRect.Bot ||
- Pict->ImageLoc.Right < DispRect.Left ||
- Pict->ImageLoc.Bot < DispRect.Top ) {
-
- return;
- }
-
- if (Pict->ImageLoc.Left < DispRect.Left) {
- Pict->ClipImage.Left = DispRect.Left;
- POLeft = -Pict->ImageLoc.Left + Pict->LeftMarg;
- } else {
- Pict->ClipImage.Left = Pict->ImageLoc.Left;
- POLeft = 0;
- }
-
- if (Pict->ImageLoc.Top < DispRect.Top) {
- Pict->ClipImage.Top = DispRect.Top;
- POTop = -Pict->ImageLoc.Top + Pict->TopMarg;
- } else {
- Pict->ClipImage.Top = Pict->ImageLoc.Top;
- POTop = 0;
- }
-
- if (Pict->ImageLoc.Right <= DispRect.Right) {
- Pict->ClipImage.Right = Pict->ImageLoc.Right;
- PORight = Pict->CountX-1;
- } else {
- Pict->ClipImage.Right = DispRect.Right;
- PORight = DispRect.Right - Pict->ImageLoc.Left;
- }
-
- if (Pict->ImageLoc.Bot <= DispRect.Bot) {
- Pict->ClipImage.Bot = Pict->ImageLoc.Bot;
- POBot = Pict->CountY - 1;
- } else {
- Pict->ClipImage.Bot = DispRect.Bot;
- POBot = DispRect.Bot - Pict->ImageLoc.Top;
- }
-
- wind_Rp = Window->RPort;
-
- #ifdef TEMPWINDOW
- tmp_Rp = TempWind->RPort;
- #else
- tmp_Rp = &Pict->ScrollRp;
- #endif
-
- if (POLeft < PORight && POTop < POBot) {
-
- /* Now copy temp rastport data to window */
-
- #ifdef SAFEBLIT
- SafeClipBlit(TempWind, POLeft, POTop, Window,
- Pict->ClipImage.Left, Pict->ClipImage.Top,
- PORight - POLeft + 1, POBot - POTop + 1, 0xc0,
- __LINE__);
- #else
- ClipBlit(tmp_Rp, POLeft, POTop, wind_Rp,
- Pict->ClipImage.Left, Pict->ClipImage.Top,
- PORight - POLeft + 1, POBot - POTop + 1, 0xc0);
- #endif
-
- #if 0
- printf("l %d t %d r %d b %d\n",POLeft, POTop, PORight, POBot);
- printf("width %d height %d\n",
- PORight - POLeft + 1, POBot - POTop + 1);
- #endif
- }
-
- Pict->DataClip.Left = POLeft;
- Pict->DataClip.Right = PORight;
- Pict->DataClip.Top = POTop;
- Pict->DataClip.Bot = POBot;
-
- /* Undraw the old picture */
-
- SetAPen(wind_Rp, 0);
-
- if (Pict->ClipImage.Left > SaveRect.Left) {
-
- FillCheck(Window, SaveRect.Left, SaveRect.Top,
- Pict->ClipImage.Left, SaveRect.Bot);
- } else
- if (Pict->ClipImage.Right < SaveRect.Right) {
-
- FillCheck(Window, Pict->ClipImage.Right, Pict->ClipImage.Top,
- SaveRect.Right, SaveRect.Bot);
- }
-
- if (Pict->ClipImage.Top > SaveRect.Top) {
-
- FillCheck(Window, SaveRect.Left, SaveRect.Top,
- SaveRect.Right, Pict->ClipImage.Top);
- } else
- if (Pict->ClipImage.Bot < SaveRect.Bot) {
-
- FillCheck(Window, SaveRect.Left, Pict->ClipImage.Bot,
- SaveRect.Right, SaveRect.Bot);
- }
- }
-
- FillCheck(Window,src_x,src_y,dst_x,dst_y)
- struct Window *Window;
- int src_x,src_y,dst_x,dst_y;
- {
- if (src_x < 0 || src_x > Window->Width) {
- #ifdef DEBUG
- printf("Bad Fill src_x %d Width %d\n",
- src_x,Window->Width);
- #endif
- return;
- }
-
- if (src_y < 0 || src_y > Window->Height) {
- #ifdef DEBUG
- printf("Bad Fill src_y %d Height %d\n",
- src_y,Window->Height);
- #endif
- return;
- }
-
- if (dst_x < 0 || dst_x > Window->Width) {
- #ifdef DEBUG
- printf("Bad Fill dst_x %d Width %d\n",
- dst_x,Window->Width);
- #endif
- return;
- }
-
- if (dst_y < 0 || dst_y > Window->Height) {
- #ifdef DEBUG
- printf("Bad Fill dst_y %d Height %d\n",
- dst_y,Window->Height);
- #endif
- return;
- }
- if (src_x > dst_x) {
- #ifdef DEBUG
- printf("inverted rect fill\n");
- #endif
- return;
- }
- if (src_y > dst_y) {
- #ifdef DEBUG
- printf("end for end flipped rect fill\n");
- #endif
- return;
- }
- RectFill(Window->RPort, src_x,src_y,dst_x,dst_y);
- }
-
- AllocScrollTemp( Pict )
- register struct Picture *Pict;
- {
- LONG Plane;
- PLANEPTR t;
-
- extern struct MenuItem ScrollSub[];
-
- static ScrollInited;
-
- extern struct NewScreen NewScreen;
-
- if ( !ScrollOn )
- return;
-
- #ifdef TEMPWINDOW
-
- NewTemp.Width = Pict->Window->Width;
- NewTemp.Height = Pict->Window->Height;
- NewTemp.LeftEdge = NewScreen.Width - NewTemp.Width-2;
- NewTemp.TopEdge = 0;
- NewTemp.Screen = screen;
- TempWind = OpenWindow( &NewTemp );
- /*WindowToBack( TempWind );*/
- return( SUCCESSFUL );
-
- #else
-
- if ( Pict->ScrollRp.BitMap == NULL ) {
-
- InitRastPort( &Pict->ScrollRp );
- Pict->ScrollRp.BitMap = &Pict->ScrollBitMap;
- }
-
- InitBitMap( &Pict->ScrollBitMap, (long) NewScreen.Depth,
- Pict->CountX, Pict->CountY);
-
- for (Plane = 0; Plane < NewScreen.Depth; Plane++) {
-
- t = (PLANEPTR) AllocRaster(Pict->CountX, Pict->CountY);
- Pict->ScrollBitMap.Planes[Plane] = (PLANEPTR) t;
-
- if (t == NULL) {
- FreeScrollTemp( Pict );
- return(UNSUCCESSFUL);
- }
- }
- return(SUCCESSFUL);
- #endif
- }
-
- FreeScrollTemp( Pict )
- struct Picture *Pict;
- {
- LONG Plane;
-
- if (Pict->Flags & SCROLL_HAPPENED) {
-
- #ifdef TEMPWINDOW
- CloseWindow( TempWind );
- #else
-
- for (Plane = 0; Plane < Pict->ScrollBitMap.Depth; Plane++) {
-
- if (Pict->ScrollBitMap.Planes[Plane]) {
-
- FreeRaster( (char *) Pict->ScrollBitMap.Planes[Plane],
- Pict->CountX,Pict->CountY);
- Pict->ScrollBitMap.Planes[Plane] = NULL;
- }
- }
- #endif
- }
- ResetScrollRects(Pict);
- }
-
- ResetScrollRects(Pict)
- struct Picture *Pict;
- {
- Pict->Flags &= ~SCROLL_HAPPENED;
-
- Pict->ImageLoc.Left = Pict->LeftMarg;
- Pict->ImageLoc.Top = Pict->TopMarg;
- Pict->ImageLoc.Right = Pict->LeftMarg + Pict->CountX - 1;
- Pict->ImageLoc.Bot = Pict->TopMarg + Pict->CountY - 1;
-
- Pict->ClipImage = Pict->ImageLoc; /* struct assignment */
- }
-
- #ifdef SAFEBLIT
- static
- SafeClipBlit( src_Wind, src_x, src_y,
- dst_Wind, dst_x, dst_y,
- width, height, min_terms,
- line_no )
-
- struct Window *src_Wind, *dst_Wind;
- LONG src_x, src_y, dst_x, dst_y, width, height, min_terms;
- LONG line_no;
- {
-
- if (src_x < 0 || src_x > src_Wind->Width) {
- printf("Line %d Bad blit src_x %d Width %d\n",
- line_no,src_x,src_Wind->Width);
- return;
- }
-
- if (src_y < 0 || src_y > src_Wind->Height) {
- printf("Line %d Bad blit src_y %d Height %d\n",
- line_no, src_y,src_Wind->Height);
- return;
- }
-
- if (width < 1 || width > src_Wind->Width) {
- printf("Line %d Bad blit width %d\n",line_no, width);
- return;
- }
-
- if (src_x + width > src_Wind->Width) {
- printf("Line %d Blit outside %d Width %d \n",
- line_no,src_x+width,src_Wind->Width);
- return;
- }
-
- if (height < 1 || height > src_Wind->Height) {
- printf("Line %d Bad blit height %d\n",line_no,height);
- return;
- }
-
- if (src_y + height > src_Wind->Height) {
- printf("Line %d Blit outside %d Height %d \n",
- line_no,src_y+height,src_Wind->Height);
- return;
- }
-
- ClipBlit( src_Wind->RPort, src_x, src_y,
- dst_Wind->RPort, dst_x, dst_y,
- width, height, min_terms);
- }
- #endif
-
- ScrollComplex(Pict)
- struct Picture *Pict;
- {
- int left, top;
- int count_x, count_y;
- SHORT *NewCounts;
-
- count_x = Pict->Window->Width - Pict->LeftMarg - Pict->RightMarg;
- count_y = Pict->Window->Height - Pict->BotMarg - Pict->TopMarg;
-
- NewCounts = (SHORT *) safeAllocMem(count_x*count_y*sizeof(SHORT),MEMF_CLEAR);
-
- if (NewCounts == NULL) {
- DispErrMsg("Can't scroll. Out of RAM.",0);
- return;
- }
-
- ScrollData(Pict, NewCounts, count_x, count_y);
-
- FreeCounts( Pict );
-
- left = Pict->ImageLoc.Left - Pict->LeftMarg;
- top = Pict->ImageLoc.Top - Pict->TopMarg;
-
- Pict->RealLow -= Pict->RealGap * left;
- Pict->ImagLow -= Pict->ImagGap * top;
- Pict->RealHigh = Pict->RealLow + Pict->RealGap * count_x;
- Pict->ImagHigh = Pict->ImagLow + Pict->ImagGap * count_y;
-
- FreeScrollTemp(Pict);
-
- Pict->Counts = NewCounts;
- Pict->CountX = count_x;
- Pict->CountY = count_y;
- Pict->CountsSize = count_x * count_y * sizeof(*Pict->Counts);
- Pict->CurLine = 0;
- }
-
- ScrollData(Pict, NewCounts, width, height)
- register struct Picture *Pict;
- SHORT *NewCounts;
- int width, height;
- {
- int sr,sc;
- register SHORT *s_rowp, *d_rowp, *sp, *dp;
-
- s_rowp = Pict->Counts + Pict->DataClip.Top * Pict->CountX;
- d_rowp = NewCounts + (Pict->ClipImage.Top-Pict->TopMarg) * width;
-
- for (sr = Pict->DataClip.Top; sr < Pict->DataClip.Bot; sr++) {
-
- dp = d_rowp + Pict->ClipImage.Left - Pict->LeftMarg;
- sp = s_rowp + Pict->DataClip.Left;
-
- for (sc = Pict->DataClip.Left; sc < Pict->DataClip.Right; sc++) {
-
- *dp++ = *sp++;
- }
- s_rowp += Pict->CountX;
- d_rowp += width;
- }
- }
-
-